package com.waves.task.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.waves.core.constant.DbConstants;
import com.waves.core.constant.TimeConstant;
import com.waves.core.constant.redis.TaskRedisKey;
import com.waves.core.handle.TokenInterceptor;
import com.waves.core.support.EntityOperations;
import com.waves.core.utils.LoginUtils;
import com.waves.core.utils.RedisUtils;
import com.waves.core.utils.StringUtils;
import com.waves.core.web.domain.TableDataInfo;
import com.waves.core.web.domain.entities.User;
import com.waves.task.dao.TaskCommentDao;
import com.waves.task.domain.dto.TaskCommentInsertDTO;
import com.waves.task.domain.dto.TaskCommentPageDTO;
import com.waves.task.domain.entity.TaskComment;
import com.waves.task.domain.enums.RedisSetTypeEnum;
import com.waves.task.domain.pojo.TaskRedisSetPOJO;
import com.waves.task.domain.vo.TaskCommentPageVO;
import com.waves.task.event.TaskRedisSetEvent;
import com.waves.task.mapper.TaskCommentMapper;
import com.waves.task.service.TaskCommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TaskCommentServiceImpl extends ServiceImpl<TaskCommentMapper, TaskComment> implements TaskCommentService {

    private final TaskCommentDao taskCommentDao;

    private final ApplicationEventPublisher applicationEventPublisher;

    @Override
    public TableDataInfo<TaskCommentPageVO> pageTaskComment(TaskCommentPageDTO pageDTO) {
        // 分页查询
        Long userId = LoginUtils.getUserId();
        IPage<TaskCommentPageVO> taskVoPage = taskCommentDao.pageTaskComment(pageDTO).convert(t -> {
            TaskCommentPageVO taskCommentPageVO = BeanUtil.copyProperties(t, TaskCommentPageVO.class);
            // 设置是否点赞
            String likedKey = TaskRedisKey.getKey(TaskRedisKey.TASK_COMMENT_LIKED_SET, taskCommentPageVO.getId());
            Boolean likedMember = RedisUtils.sIsMember(likedKey, userId);
            taskCommentPageVO.setIsLiked(BooleanUtil.isTrue(likedMember));
            if (StringUtils.isNotEmpty(t.getImgUrl())) {
                taskCommentPageVO.setImages(Arrays.asList(t.getImgUrl().split(";")));
            }
            return taskCommentPageVO;
        });
        return TableDataInfo.build(taskVoPage);
    }

    @Override
    public Long insertTaskComment(TaskCommentInsertDTO dto) {
        TaskComment entity = new TaskComment();
        BeanUtils.copyProperties(dto, entity);
        User user = TokenInterceptor.userInfo.get();
        entity.setUserId(user.getId()).setUserAvatar(user.getAvatar());
        Optional<TaskComment> execute = EntityOperations.doCreate(baseMapper)
                .create(() -> entity)
                .update(e -> {
                    if (CollUtil.isNotEmpty(dto.getImages())) {
                        String images = String.join(";", dto.getImages());
                        e.setImgUrl(images);
                    }
                })
                .execute();
        return execute.map(TaskComment::getId)
                .orElse(DbConstants.DEFAULT_LONG_VALUE);
    }

    @Override
    public Integer deleteTaskComment(List<Long> ids) {
        return baseMapper.deleteBatchIds(ids);
    }

    /**
     * 点赞/取消点赞
     *
     * @param id
     * @return
     */
    @Override
    public boolean likeTaskComment(long id) {
        Long userId = LoginUtils.getUserId();
        String key = TaskRedisKey.getKey(TaskRedisKey.TASK_COMMENT_LIKED_SET, id);
        Boolean member = RedisUtils.sIsMember(key, userId);
        TaskComment entity = new TaskComment();
        BeanUtils.copyProperties(baseMapper.selectById(id), entity);
        return EntityOperations.doUpdate(baseMapper)
                .get(() -> {
                    if (BooleanUtil.isTrue(member)) {
                        // 如果已经点赞
                        entity.setLikedNum(entity.getLikedNum() - 1);
                    } else {
                        entity.setLikedNum(entity.getLikedNum() + 1);
                    }
                    return entity;
                })
                .update(d -> {
                })
                .successHook(thisEntity -> {
                    // 发送任务点赞、取消赞、收藏、取消收藏等操作的事件
                    TaskRedisSetPOJO pojo = new TaskRedisSetPOJO()
                            .setRedisSetTypeEnum(RedisSetTypeEnum.TASK_COMMENT_LIKED)
                            .setKey(id)
                            .setMember(userId)
                            .setTimes(TimeConstant.YEAR_TIME);
                    applicationEventPublisher.publishEvent(new TaskRedisSetEvent(this, pojo));
                })
                .execute().isPresent();
    }
}
